#ifdef SYPX_MEMCHECK
#include "mmgr.h"
#endif

#include "RendererGL2.h"
#include "Mesh.h"
#include "MeshInstance.h"
#include "Texture.h"
#include <glm/gtc/type_ptr.hpp>
#include <GL/glew.h>


namespace SypX
{
	RendererGL2::RendererGL2(void)
	{
	}

	RendererGL2::~RendererGL2(void)
	{
	}

	void RendererGL2::createTexture(Texture* tex)
	{
		if(tex->getTexIDRef() == 0)
		{
			glGenTextures(1, &tex->getTexIDRef());
		}
		glBindTexture(GL_TEXTURE_2D, tex->getTexIDRef());
		///Linear Filtering
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexImage2D(GL_TEXTURE_2D, 0, tex->getInternalFormat(), tex->getWidth(), tex->getHeight(), 0, tex->getDataFormat(), GL_UNSIGNED_BYTE, &tex->getDataRef()[0]);
	}

	void RendererGL2::deleteTexture(Texture* tex)
	{
		glDeleteTextures(1, &tex->getTexIDRef());
	}

	void RendererGL2::init(UInt width, UInt height)
	{
		glewInit();							//load gl extensions
		Renderer::init(width,height);		//Call base class
		glViewport(0, 0, width, height);	//Set Viewport

		glDisable(GL_LIGHTING);				//No normals so disable lighting
		glEnable(GL_TEXTURE_2D);			//Enable Texturing
		glShadeModel(GL_SMOOTH);
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GREATER, 0.0f);
		glEnable(GL_DEPTH_TEST);

		glEnable (GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, width, 0, height,-1.5f,1.5f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

		glColor4f(1.0f,1.0f,1.0f, 1.0f);

	}

	void RendererGL2::clearScreen(bool color, bool depth)
	{
		if(color && depth)
		{
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		}
	}

	void RendererGL2::setClearScreenColor(const Vec4& color )
	{
		Renderer::setClearScreenColor(color);
		glClearColor(color.r, color.g, color.b, color.a);
	}

	void RendererGL2::drawMesh(MeshInstance* mi)
	{
		Mesh* m = mi->getMesh();
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadMatrixf(glm::value_ptr(mi->getTransformMatrix()));
		glEnableClientState(GL_VERTEX_ARRAY);

		if(m->usesColor())
		{
			glEnableClientState(GL_COLOR_ARRAY);
		}
		else
		{//i dunno why not setting the color screws up shit, but just set it
			glColor4fv(glm::value_ptr(activeColor));
		}

		Texture* t = mi->getTexture();

		FloatArray& d = m->getDataArrayRef();
		glVertexPointer(3,GL_FLOAT,m->getStride(), &(d[0]) );

		if(t)
		{
			glBindTexture(GL_TEXTURE_2D, t->getTexIDRef());
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,m->getStride(),(char*)&(d[3]) );
		}
		else
		{
			glBindTexture(GL_TEXTURE_2D, 0);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		if(m->usesColor())
		{
			glColorPointer(4, GL_FLOAT, m->getStride(), (char*)&(d[5]));
		}
		glDrawArrays(m->getPrimitiveType(), 0, m->getNumVertices());

		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_COLOR_ARRAY);

		glPopMatrix();
	}
}
